/**
 * DUNGEONEERING
 * This project is started by Webjoch. Don't copy any content of this project
 * without permissions from Webjoch. You can contact webjoch on: webjoch@rsbuddy.com
 * 
 * Contributor:
 * - Webjoch
 * - Streammz
 * 
 * Project hosting at: http://code.google.com/p/dungeoneering/
 * Java docs: http://webjoch.nl/dung/
 */

package webjoch;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.LinkedList;

import webjoch.methods.Rooms;
import webjoch.misc.Checker;
import webjoch.misc.PaintMap;
import webjoch.process.strategies.Puzzle;
import webjoch.process.strategies.puzzles.*;
import webjoch.process.strategies.Boss;
import webjoch.process.strategies.bosses.*;
import webjoch.wrappers.Room;

import com.rsbuddy.event.events.MessageEvent;
import com.rsbuddy.event.listeners.MessageListener;
import com.rsbuddy.event.listeners.PaintListener;
import com.rsbuddy.script.ActiveScript;
import com.rsbuddy.script.Manifest;
import com.rsbuddy.script.methods.Game;
import com.rsbuddy.script.methods.Mouse;
import com.rsbuddy.script.task.TaskContainer;
import com.rsbuddy.script.util.Timer;

@Manifest(name = "Webjoch - dungeoneering", description = "", authors = "Webjoch", version = 1.0)
public class Main extends ActiveScript implements PaintListener, MessageListener, MouseMotionListener{
        protected boolean inDungeon = true;
        private static Dungeon currentDungeon;
        
        private static Timer runTime;
        private static String status = "Starting";
        
        private final static LinkedList<Puzzle> puzzles = new LinkedList<Puzzle>();
        private final static LinkedList<Boss> bosses = new LinkedList<Boss>();
        public static int[] unSolvedPuzzles = {3, 7};
        
        public static boolean ignoreCurrentRoom = false; // do not process the current room, when doing a puzzle for the second time.
        
        //gui
        private static boolean rush = true;
        IcePad icePad = new IcePad();
                
        @Override
        public boolean onStart(){
                puzzles.add(new Monolith());
                puzzles.add(new SlidingBlock());
                puzzles.add(new Emote());
                puzzles.add(new Traps());
                puzzles.add(new LargeCrystal());
                puzzles.add(new ThreeStatues());
                puzzles.add(new ImbueTiles());
                puzzles.add(new Maze());
                puzzles.add(new WinchBridge());
                puzzles.add(new SlidingStatues());
                puzzles.add(new Ghosts());
                puzzles.add(new DemagedConstruct());
                puzzles.add(new Levers());
                puzzles.add(new IcePad());
                puzzles.add(new Pondskaters());
                puzzles.add(new IcePad());
                
                bosses.add(new GluttonousBehemoth());
                bosses.add(new AstreaFrostweb());
                bosses.add(new IcyBones());
                
                TaskContainer task = getContainer();
                task.submit(new Checker());
                
                Mouse.setSpeed(3);
                runTime = new Timer(0);
                return true;
        }
        
        @Override
        public int loop(){
                if (Game.getClientState() == 12) return 1;
                
                int sleep = 1;
                try{
                        if (inDungeon){
                                if (currentDungeon == null){
                                        currentDungeon = new Dungeon();
                                }
                                sleep = currentDungeon.loop();          
                        }
                }catch(NullPointerException e){
                        log.warning("");
                        log.warning("NullPointerException");
                        for (StackTraceElement info : e.getStackTrace()){
                                if (info.getFileName() != null){
                                        log.warning("File: "+ info.getFileName()+", line: "+info.getLineNumber());
                                }
                        }
                }
                return sleep;
        }

        public static void setDungeon(Dungeon dungeon){
                currentDungeon = dungeon;
        }
        
        public static long getRunTime(){
                return runTime.getElapsed();
        }
        
        public static Dungeon getDungeon(){
                return currentDungeon;
        }
        
        public static boolean shouldRush(){
                return rush;
        }
        
        public static long time(){
                return runTime.getElapsed();
        }
        
        public static void setStatus(String status){
                Main.status = status;
        }
        
        public static Puzzle[] getPuzzles(){
                return puzzles.toArray(new Puzzle[puzzles.size()]);
        }
        
        public static Boss[] getBosses(){
            return bosses.toArray(new Boss[bosses.size()]);
        }
        
        
        @Override
        public void onRepaint(Graphics g1) {
            Graphics2D g = (Graphics2D) g1;         
            
            PaintMap.onRepaint(g1);
            
            if (Rooms.getLocalRoom().getType() == Room.Type.PUZZLE){
	            for (Puzzle p : getPuzzles()){
	            	if (p.isValid()){
	            		p.onRepaint(g);
	            	}
	            }
            }
            
            g.setFont(new Font("Arial", 1, 12));
	        g.setColor(new Color(204, 0, 51));
	        
	        g.setFont(new Font("Arial", 0, 12));
	        g.drawString("Status: "+ status, 11, 100);
	        g.drawString("Links: "+ getDungeon().getMap().length, 11, 115);
	        g.drawString("Keydoors: "+ getDungeon().getKeyDoors().length, 11, 130);
	        g.drawString("Tasks: "+ getDungeon().getTasks().length, 11, 145);
	        g.drawString("Room location: ("+ Rooms.getLocalRoom().getLocalLocation(true)[0] + ", "+ Rooms.getLocalRoom().getLocalLocation(true)[1]+")", 11, 160);
        }

        @Override
        public void messageReceived(MessageEvent e){
    		System.out.println("Test");
            for (Puzzle puzzle : puzzles){
            	puzzle.messageReceived(e);
            }
        	getDungeon().messageReceived(e);
        }

        @Override
        public void mouseMoved(MouseEvent e) {
                PaintMap.highligh = e.getPoint().x > 240 && e.getPoint().x < 540 && e.getPoint().y > 15 && e.getPoint().y < 265;
        }

        @Override
        public void mouseDragged(MouseEvent e) {                
        }
}